﻿/* 
 * Copyright (c) 2011-12-12 Andrey Bulygin
 * 
 * This file is part of Interceptor.
 * Interceptor is free software: you can redistribute it and/or modify it under the terms of the GNU 
 * Library General Public License as published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * Interceptor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 
 * the GNU Library General Public License for more details. You should have received a copy of the GNU 
 * Library General Public License along with Interceptor. If not, write to the Free Software Foundation, Inc., 59 
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Interceptor.Core;

namespace Interceptor
{
	public static class ObjectExtension
	{
		#region extenders
		#region ctors
		public static T GetCtor<T>(this Type type) where T:class
		{
			return SubtypeFactory.CreateConstructorDelegate(type, typeof(T)) as T;
		}
		#endregion
		internal static Type ExtendWith(this Type type, Type interceptorsHolder)
		{
			return SubtypeFactory.MakeSubtypeAndInjectInterceptors(type, interceptorsHolder);
		}
		internal static Type ExtendWith<TInterceptorsHolder>(this Type type)
		{
			return SubtypeFactory.MakeSubtypeAndInjectInterceptors(type, typeof(TInterceptorsHolder));
		}
		#endregion
		#region DECORATORS
		public static IDecorator DecorateWith(this object obj, object interceptorsHolder)
		{
			return GetDecoratorFactory(obj, interceptorsHolder.GetType())(obj, interceptorsHolder);
		}
		private static Func<object, object, IDecorator> GetDecoratorFactory(object obj, Type interceptor)
		{
			return KeyValueCache<Pair<Type, Type>, Func<object, object, IDecorator>>.TryToGet(
										new Pair<Type, Type>(obj.GetType(), interceptor),
										(p) => DecoratorFactory.MakeInterceptorFactoryDelegate(obj, interceptor));
		}
		#endregion
	}
}
